home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
c
/
getfreespace
/
mcfree.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-01
|
6KB
|
156 lines
/* McFree v2.1 by Mack Lifeguard. This program is hereby placed in the
* public domain. You can use it for whatever purpose you like, just don't
* hold me responsible for any problems it may cause. */
/* This program is a very simple but interesting example of how you can
* use the AmigaDOS libraries to cut your executables' size in half. When
* compiling this program be sure to link with "amiga.lib", since the
* sprintf() function in amiga.lib uses the internal ROM's printf() function.
* Thus, you're program is now 3k smaller! Be warned, some features of the
* regular sprintf() do not work 100% on the amiga.lib sprintf(). Mainly you
* are limited to only 140 bytes of the final outputting string (anything
* above that and you get an instant guru), and you can't use the "%.*"
* qualifier. But for small programs like these, the sprintf() in amiga.lib
* works great. Again, you must include "amiga.lib" in your LINK list. If you
* are using SAS C, then just go to scopts and enter "amiga.lib" in the
* Libraries/Objects section under the Link gadget. */
/* Many more space-saving techniques are used. Primarily they are
* compiling options. I won't go into detail on how they work, but you can
* see for yourself the settings in the included SCOPTIONS file. */
/* If you compile this program using standard SAS C options, you will get
* an executable of size 6619 bytes. Using the included SCOPTIONS file you
* will get a filesize of 1688. A considerable difference! */
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <proto/dos.h> /* We use pragmas, so no need for opening libraries.
* The pragmas in <proto/dos.h> automatically call
* each dos function directly. */
void errorf(char *text);
char out[80], *p;
void main(int argc,char *argv[])
{
/* We use the external argc variable to gauge the number of arguments. */
/* Argc always returns at least a value of 1 (one). */
__aligned struct InfoData info; /* Just to be safe, use a 4 byte boundary. */
int x,size=0;
BPTR lock;
for (p=out; p<&out[80]; p++)
*p=NULL;
Write(Output(), "\nMcFree v2.1 by Mack Lifeguard\n\n",32);
/* By using the Output() device, in combination with Write(), the program
* becomes considerably smaller. Instead of using C's printf(), which takes
* up an additional 3k. */
if (argc==1)
Write(Output(),"USAGE: McFree <Volume1> ... [Volume29]\n\n",40);
/* As mentioned earlier, if there is only one argument (argc==1), then the
* user did not input any parameters, so we send a message and exit. */
for (x=1;x<argc;x++)
{
/* OK, so the user entered some arguments, lets check to see if they
* are valid I/O devices, then we calculate their available free
* storage. NOTE: This is an approximation based on number of blocks
* used. The exact free storage can only be calculated by going in and
* adding up each individual file size. By using blocks to calculate,
* you may be off by a few bytes or so, but you can get the information
* in a few CPU cycles, without scanning the entire device. */
/* Now, lets check to see if we can get a Lock() on the device. */
if ( (lock=Lock (argv[x], ACCESS_READ))==NULL)
errorf(argv[x]); /* No deal, lets send an error message and continue. */
else
{
/* Target is locked! But we're not through yet, lets be extra safe and
* check to see if we can get a succesful Info() on it. */
if ( !Info(lock,&info) )
errorf(argv[x]); /* We send an error message but continue loop. */
else
{
/* Here is the main calculation part of the program. The Info()
* function from Amigados has filled our file I/O structure.
* Remember? The one we aligned on a 4 byte boundary? OK, so now
* we simply do some multiplication and substraction. The labels
* should be self-explanatory, we are merely subtracting the used
* blocks from the available blocks. Then we just multiply the
* result by the number of bytes in each block. Keep in mind, not
* all devices have the same number of bytes per block! */
size=(info.id_NumBlocks - info.id_NumBlocksUsed) * info.id_BytesPerBlock;
sprintf(out, "Drive %s has %ld bytes free. \n",argv[x],size);
Write(Output(), out, strlen(out));
}
UnLock(lock); /* Always Unlock() what you Lock. If you don't, then
* you will get an "Object In Use" error the next
* time you try to access a locked file/device. */
}
} /* End of main for loop. */
_exit(0); /* Always exit with 0 on success. */
/* NOTE: I used the special _exit() function (notice the
* underscore) because the normal exit() function frees memory and
* closes files for you. However, since we are not using standard C
* I/O, that is, we are using AmigaDOS functions from libraries,
* then we really don't need the features of the regular exit().
* The special _exit() simply returns control to the operating
* system, without freeing memory or closing files, WE are expected
* to do that. I use this function because it saves about 2k. */
}
void errorf(char *text)
{
sprintf(out, ">>Error reading volume: \"%.20s\"\n",text);
/* Notice how I used the special sprintf() quailifier "%.20s", this
* gurantees that a MAXIMUM of 20 characters will be used in the final
* string. Any characters after 20 are simply ignored in the conversion.
* This is just a safeguard against breaking the 140 byte limit on the
* special amiga.lib sprintf() function. If we were using the standard
* C sprintf() then there wouldn't be any need for this check. */
Write(Output(), out, strlen(out) );
}
/*
CONTACT INFO
=-=-=-=-=-=-
If you have any questions, bug reports, suggestiongs, you can contact me at
the following:
Hangar 18: (713) 488-3055
International Chaos: (713) 999-3640
Complex Corrosion: (612) 773-0522 [4 nodes]
Danse Macabre: (713) 324-1165
-Mack Lifeguard/Dual Crew-Shining
*/